
#include "parser.h"
#include <string.h>


#if defined(ANDROID)
#include "android/log.h"
#include "utils/Log.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "SerialControl"
#else
#include <stdio.h>
#define ALOGD printf
#endif

namespace serial {

Parser::Parser()
{
}

Parser::~Parser()
{
}


int Parser::parse(const char * buf, int len, unsigned char * outbuf, int outlen, const Parser::FSM** pfsm)
{
    if (mFsms.empty()) {
        ALOGD("No fsm.. drop data.");
        return -1;
    }

    mBuffer.append(buf, len);

    if (mBuffer.empty())
        return -1;

    if (mBuffer.length() > 10240) {
        mBuffer.assign(0);
        return -1;
    }

    for (std::list<FSM*>::iterator it = mFsms.begin(); it != mFsms.end(); it++) {
        FSM* fsm = *it;

        for (int i = 0; i < mBuffer.length(); i++) {
            int ret = fsm->onData(mBuffer[i]);
            if (ret < 0) {
                fsm->reset();
                break;
            }
            if (ret == 0)
                continue;
            // > 0
            int ll = i + 1;
            if (outbuf != NULL && outlen > 0) {
                ll = (i + 1) < outlen ? (i + 1) : outlen;
                memcpy(outbuf, mBuffer.buffer(), ll);
            }
            mBuffer.erase_before(i + 1);
            fsm->reset();
            if (pfsm != NULL)
                *pfsm = fsm;
            return ll;
        }
    }

    // ALOGD("erase %02x\n", mBuffer[0] & 0xff);
    mBuffer.erase_before(1);
    if (mBuffer.length() > 0)
        return 0;
    return -1;
}

void Parser::addFsm(Parser::FSM* fsm)
{
    mFsms.push_back(fsm);
    fsm->reset();
}

void Parser::resetAllFsms()
{
    for (std::list<FSM*>::iterator it = mFsms.begin(); it != mFsms.end(); it++) {
        FSM* fsm = *it;
        fsm->reset();
    }
}

} // namespace serial

